package dk.modified.reshary;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.InputType;
import android.text.Spannable;
import android.text.SpannableString;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.EditText;

public class Util {
	public static Map<String, String> formatResponse(HttpResponse response) {

		Map<String, String> responsearr = new HashMap<String, String>();
		String responseBody = null;
		try {
			responseBody = EntityUtils.toString(response.getEntity());
			JSONObject jsonObj = new JSONObject(responseBody);
			Iterator<?> keys = jsonObj.keys();

			while (keys.hasNext()) {
				String key = keys.next().toString();
				responsearr.put(key, jsonObj.getString(key));
			}

		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return responsearr;

	}
	
	public static int getPhotoRotationDegree(String imagePath) {
		int rotate = 0;
		try {
			File imageFile = new File(imagePath);
			ExifInterface exifDataReader = new ExifInterface(imageFile.getAbsolutePath());
			int orientation = exifDataReader.getAttributeInt(ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);

			switch (orientation) {
				case ExifInterface.ORIENTATION_ROTATE_270:
					rotate = 270;
					break;
				case ExifInterface.ORIENTATION_ROTATE_180:
					rotate = 180;
					break;
				case ExifInterface.ORIENTATION_ROTATE_90:
					rotate = 90;
					break;
			}
		} catch (IOException e) {
			Log.e("CATROID", "Could not find file to initialize ExifInterface.", e);
		}
		return rotate;
	}

	// NOT CURRENTLY USED
	// public static String getImagePath(Uri uri, Context c) {
	//
	// try {
	// Cursor cursor = c.getContentResolver().query(uri, null, null, null,
	// null);
	// cursor.moveToFirst();
	// String document_id = cursor.getString(0);
	// document_id = document_id
	// .substring(document_id.lastIndexOf(":") + 1);
	// cursor.close();
	//
	// cursor = c
	// .getContentResolver()
	// .query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
	// null, MediaStore.Images.Media._ID + " = ? ",
	// new String[] { document_id }, null);
	// cursor.moveToFirst();
	// String path = cursor.getString(cursor
	// .getColumnIndex(MediaStore.Images.Media.DATA));
	// cursor.close();
	// return path;
	// } catch (Exception ex) {
	// return uri.getPath();
	// }
	//
	// }
	//
	// public static int neededRotation(String path) {
	// try {
	// ExifInterface exif = new ExifInterface(path);
	// int orientation = exif.getAttributeInt(
	// ExifInterface.TAG_ORIENTATION,
	// ExifInterface.ORIENTATION_NORMAL);
	//
	// if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
	// return 270;
	// }
	// if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
	// return 180;
	// }
	// if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
	// return 90;
	// }
	// return 0;
	//
	// } catch (FileNotFoundException e) {
	// e.printStackTrace();
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	// return 0;
	// }

	public static double getAngleOfLineBetweenTwoPoints(float x1, float y1,
			float x2, float y2) {
		double xDiff = x1 - x2;
		double yDiff = y1 - y2;
		return Math.toDegrees(Math.atan2(yDiff, xDiff));
	}

	public static float oppositeValue(float f) {
		if (f <= 0) {
			return Math.abs(f);
		} else {
			return f * (-1);
		}
	}

	public static void setActionBar(Context c, String title) {
		SpannableString s = new SpannableString(title);
		s.setSpan(new TypefaceSpan(c, "CalibriBoldItalic.ttf"), 0, s.length(),
				Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

		// Update the action bar title with the TypefaceSpan instance
		ActionBar actionBar = ((Activity) c).getActionBar();
		actionBar.setTitle(s);

	}

	public static void intentSendBackUser(Context c) {

		SharedPreferences sharedpreferences = c.getSharedPreferences(
				"dk.modified.reshary", Context.MODE_PRIVATE);
		Editor editor = sharedpreferences.edit();
		editor.putString("securitytoken", "null");
		editor.putString("userid", "null");
		editor.commit();

		Intent loginscreen = new Intent(c.getApplicationContext(),
				SplashScreen.class);
		loginscreen.putExtra("failure",
				"You have been sent back, invalid login.");
		loginscreen.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
				| Intent.FLAG_ACTIVITY_CLEAR_TASK);
		c.startActivity(loginscreen);

	}

	public static float calculateDifference(float a, float b) {
		float res = 0f;
		if (a >= b) {
			res = (a - b);
		} else {
			res = (b - a);
		}
		return res;
	}

	public static Map<String, String> newformatResponse(String response) {

		Map<String, String> responsearr = new HashMap<String, String>();

		JSONObject jsonObj = null;
		try {
			jsonObj = new JSONObject(response);
		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		Iterator<?> keys = jsonObj.keys();

		while (keys.hasNext()) {
			String key = keys.next().toString();
			try {
				responsearr.put(key, jsonObj.getString(key));
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return responsearr;

	}

	public static Map<String, Object> specialformatResponse(String response) {

		Map<String, Object> responsearr = new HashMap<String, Object>();

		JSONObject jsonObj = null;
		try {
			jsonObj = new JSONObject(response);
		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		Iterator<?> keys = jsonObj.keys();

		while (keys.hasNext()) {
			String key = keys.next().toString();
			try {
				if (key.equals("share")) {
					ArrayList<Object> objectArr = new ArrayList<Object>();

					JSONArray jsonArr = jsonObj.getJSONArray(key);
					for (int i = 0; i < jsonArr.length(); i++) {

						JSONObject jsonObj2 = (JSONObject) jsonArr.get(i);
						Iterator<?> keys2 = jsonObj2.keys();
						Map<String, String> values = new HashMap<String, String>();
						while (keys2.hasNext()) {
							String key2 = keys2.next().toString();
							values.put(key2, jsonObj2.getString(key2));
							// values.add(jsonObj2.getString(key2));
						}

						objectArr.add(values);
					}

					responsearr.put(key, objectArr);

				} else {
					responsearr.put(key, jsonObj.getString(key));
				}

			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return responsearr;

	}

	/**
	 * Returns the contents of the file in a byte array
	 * 
	 * @param file
	 *            File this method should read
	 * @return byte[] Returns a byte[] array of the contents of the file
	 */
	@SuppressWarnings("resource")
	public static byte[] getBytesFromFile(File file) throws IOException {

		InputStream is = new FileInputStream(file);
		System.out.println("\nDEBUG: FileInputStream is " + file);

		// Get the size of the file
		long length = file.length();
		System.out.println("DEBUG: Length of " + file + " is " + length + "\n");

		/*
		 * You cannot create an array using a long type. It needs to be an int
		 * type. Before converting to an int type, check to ensure that file is
		 * not loarger than Integer.MAX_VALUE;
		 */
		if (length > Integer.MAX_VALUE) {
			System.out.println("File is too large to process");
			return null;
		}

		// Create the byte array to hold the data
		byte[] bytes = new byte[(int) length];

		// Read in the bytes
		int offset = 0;
		int numRead = 0;
		while ((offset < bytes.length)
				&& ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) {

			offset += numRead;

		}

		// Ensure all the bytes have been read in
		if (offset < bytes.length) {
			throw new IOException("Could not completely read file "
					+ file.getName());
		}

		is.close();
		return bytes;

	}

	public static Map<String, Object> specialformatResponseCategories(
			String response) {

		Map<String, Object> responsearr = new HashMap<String, Object>();

		JSONObject jsonObj = null;
		try {
			jsonObj = new JSONObject(response);
		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		ArrayList<Category> categoryArrList = new ArrayList<Category>();

		Iterator<?> keys = jsonObj.keys();

		while (keys.hasNext()) {
			String key = keys.next().toString();
			try {
				if (key.equals("cat")) {

					JSONArray jsonArr = jsonObj.getJSONArray(key);
					for (int i = 0; i < jsonArr.length(); i++) {

						ArrayList<CategorySub> children = null;
						String name = "";
						int cat_id = 0;
						int parent = 0;

						JSONObject json_categories = (JSONObject) jsonArr
								.get(i);

						if (json_categories.has("name")) {
							name = json_categories.getString("name");
						}

						if (json_categories.has("cat_id")) {
							cat_id = json_categories.getInt("cat_id");
						}

						if (json_categories.has("parent")) {
							parent = json_categories.getInt("parent");
						}

						if (json_categories.has("child")) {
							JSONArray json_children = json_categories
									.getJSONArray("child");
							children = new ArrayList<CategorySub>();
							for (int k = 0; k < json_children.length(); k++) {

								JSONObject json_children_categories = (JSONObject) json_children
										.get(k);
								String childname = "";
								int child_cat_id = 0;
								int child_parent = 0;

								if (json_children_categories.has("name")) {
									childname = json_children_categories
											.getString("name");
								}

								if (json_children_categories.has("cat_id")) {
									child_cat_id = json_children_categories
											.getInt("cat_id");
								}

								if (json_children_categories.has("parent")) {
									child_parent = json_children_categories
											.getInt("parent");
								}

								children.add(new CategorySub(child_cat_id,
										childname, child_parent));
							}
						} else {
							children = new ArrayList<CategorySub>();
						}

						categoryArrList.add(new Category(cat_id, name, parent));
						categoryArrList.get(i).setChildren(children);

					}

					responsearr.put(key, categoryArrList);

				} else {
					responsearr.put(key, jsonObj.getString(key));
				}

			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return responsearr;

	}

	public static boolean deleteDirectory(File path) {
		if (path.exists()) {
			File[] files = path.listFiles();
			if (files == null) {
				return true;
			}
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					deleteDirectory(files[i]);
				} else {
					files[i].delete();
				}
			}
		}
		return (path.delete());
	}

	public static String encodeTobase64(Bitmap image) {
		String byteImage = null;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 70, baos);
		byte[] b = baos.toByteArray();
		try {
			System.gc();
			byteImage = Base64.encodeToString(b, Base64.DEFAULT);
		} catch (Exception e) {
			e.printStackTrace();
		} catch (OutOfMemoryError e) {
			baos = new ByteArrayOutputStream();
			image.compress(Bitmap.CompressFormat.JPEG, 70, baos);
			b = baos.toByteArray();
			byteImage = Base64.encodeToString(b, Base64.DEFAULT);
			Log.e("Bitmap", "Out of memory error catched");
		}
		return byteImage;
	}

	public static String convertUriToBase64(Context c, Uri uri) {
		String data = null;
		ContentResolver cr = c.getContentResolver();
		int[] screenSize = getScreenSize(c);

		try {
			InputStream inputStream = cr.openInputStream(uri);
			Bitmap bitmap = decodeSampledBitmapFromURI(inputStream,
					screenSize[0], screenSize[1]);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 70, baos);
			data = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (OutOfMemoryError e) {
			InputStream inputStream = null;
			try {
				inputStream = cr.openInputStream(uri);
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			Bitmap bitmap = decodeSampledBitmapFromURI(inputStream,
					screenSize[0], screenSize[1]);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 70, baos);
			data = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
		}
		return data;
	}

	public static int[] getScreenSize(Context c) {
		DisplayMetrics metrics = c.getResources().getDisplayMetrics();
		int width = metrics.widthPixels;
		int height = metrics.heightPixels;

		int[] arr = new int[2];
		arr[0] = width;
		arr[1] = height;
		return arr;
	}

	public static Bitmap decodeSampledBitmapFromURI(InputStream inputStream,
			int reqWidth, int reqHeight) {

		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		BitmapFactory.decodeStream(inputStream, null, options);
		options.inJustDecodeBounds = true;
		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth,
				reqHeight);
		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeStream(inputStream, null, options);
	}

	public static int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			final int halfHeight = height / 2;
			final int halfWidth = width / 2;

			// Calculate the largest inSampleSize value that is a power of 2 and
			// keeps both
			// height and width larger than the requested height and width.
			while ((halfHeight / inSampleSize) > reqHeight
					&& (halfWidth / inSampleSize) > reqWidth) {
				inSampleSize *= 2;
			}
		}

		return inSampleSize;
	}

	public static InputStream getInputStreamFromUrl(Context context, String url) {
		PackageInfo pInfo = null;
		try {
			pInfo = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
		} catch (NameNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		String version = pInfo.versionName;

		InputStream content = null;
		try {
			HttpClient client = new DefaultHttpClient();
			client.getParams().setParameter(CoreProtocolPNames.USER_AGENT,
					"reshary.com KBJdfbkjf88jkb Agent " + version);
			HttpResponse response = client.execute(new HttpGet(url));
			content = response.getEntity().getContent();
		} catch (Exception e) {
			Log.d("[GET REQUEST]", "Network exception", e);
		}
		return content;
	}

	public static String getUserAgent(Context c) {
		PackageInfo pInfo = null;
		try {
			pInfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0);
		} catch (NameNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		String version = pInfo.versionName;

		return "reshary.com KBJdfbkjf88jkb Agent " + version;
	}

	public static void sharedPrefsPutLogin(Context c,
			Map<String, String> postResult) {
		SharedPreferences sharedpreferences = c.getSharedPreferences(
				"dk.modified.reshary", Context.MODE_PRIVATE);
		Editor editor = sharedpreferences.edit();
		editor.putString("securitytoken", postResult.get("securitytoken"));
		editor.putString("userid", postResult.get("userid"));
		editor.commit();
	}

	public static void intentLogin(Context c) {
		Intent loggedin = new Intent(c.getApplicationContext(),
				SplashScreen.class);
		loggedin.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
				| Intent.FLAG_ACTIVITY_CLEAR_TASK);
		c.startActivity(loggedin);
	}

	/**
	 * Get a file path from a Uri. This will get the the path for Storage Access
	 * Framework Documents, as well as the _data field for the MediaStore and
	 * other file-based ContentProviders.
	 * 
	 * @param context
	 *            The context.
	 * @param uri
	 *            The Uri to query.
	 * @author paulburke
	 */
	@SuppressLint("NewApi")
	public static String getPath(final Context context, final Uri uri) {

		final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
		Log.d("TEST", isKitKat + "");

		// DocumentProvider
		if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
			// ExternalStorageProvider
			if (isExternalStorageDocument(uri)) {
				final String docId = DocumentsContract.getDocumentId(uri);
				final String[] split = docId.split(":");
				final String type = split[0];

				if ("primary".equalsIgnoreCase(type)) {
					return Environment.getExternalStorageDirectory() + "/"
							+ split[1];
				}

				// TODO handle non-primary volumes
			}
			// DownloadsProvider
			else if (isDownloadsDocument(uri)) {

				final String id = DocumentsContract.getDocumentId(uri);
				final Uri contentUri = ContentUris.withAppendedId(
						Uri.parse("content://downloads/public_downloads"),
						Long.valueOf(id));

				return getDataColumn(context, contentUri, null, null);
			}
			// MediaProvider
			else if (isMediaDocument(uri)) {
				final String docId = DocumentsContract.getDocumentId(uri);
				final String[] split = docId.split(":");
				final String type = split[0];
				
				Uri contentUri = null;
				if ("image".equals(type)) {
					contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
				} else if ("video".equals(type)) {
					contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
				} else if ("audio".equals(type)) {
					contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
				}

				final String selection = "_id=?";
				final String[] selectionArgs = new String[] { split[1] };

				return getDataColumn(context, contentUri, selection,
						selectionArgs);
			}
		}
		// MediaStore (and general)
		else if ("content".equalsIgnoreCase(uri.getScheme())) {
			return getDataColumn(context, uri, null, null);
		}
		// File
		else if ("file".equalsIgnoreCase(uri.getScheme())) {
			return uri.getPath();
		}

		return null;
	}

	/**
	 * Get the value of the data column for this Uri. This is useful for
	 * MediaStore Uris, and other file-based ContentProviders.
	 * 
	 * @param context
	 *            The context.
	 * @param uri
	 *            The Uri to query.
	 * @param selection
	 *            (Optional) Filter used in the query.
	 * @param selectionArgs
	 *            (Optional) Selection arguments used in the query.
	 * @return The value of the _data column, which is typically a file path.
	 */
	public static String getDataColumn(Context context, Uri uri,
			String selection, String[] selectionArgs) {

		Cursor cursor = null;
		final String column = "_data";
		final String[] projection = { column };

		try {
			cursor = context.getContentResolver().query(uri, projection,
					selection, selectionArgs, null);
			if (cursor != null && cursor.moveToFirst()) {
				final int column_index = cursor.getColumnIndexOrThrow(column);
				return cursor.getString(column_index);
			}
		} finally {
			if (cursor != null)
				cursor.close();
		}
		return null;
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is ExternalStorageProvider.
	 */
	public static boolean isExternalStorageDocument(Uri uri) {
		return "com.android.externalstorage.documents".equals(uri
				.getAuthority());
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is DownloadsProvider.
	 */
	public static boolean isDownloadsDocument(Uri uri) {
		return "com.android.providers.downloads.documents".equals(uri
				.getAuthority());
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is MediaProvider.
	 */
	public static boolean isMediaDocument(Uri uri) {
		return "com.android.providers.media.documents".equals(uri
				.getAuthority());
	}
	
	public static File saveGif(byte[] data) {

		File dir = new File(Environment.getExternalStorageDirectory()
				.getAbsolutePath() + "/reshary/gif/");
		dir.mkdirs();

		File file = new File(Environment.getExternalStorageDirectory()
				.getAbsolutePath()
				+ "/reshary/gif/"
				+ System.currentTimeMillis() + ".gif");
		try {
			file.createNewFile();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		file.mkdirs();
		FileOutputStream fos = null;

		try {
			fos = new FileOutputStream(file);

			// Writes bytes from the specified byte array to this file output
			// stream
			fos.write(data);
			return file;
		}

		catch (FileNotFoundException e) {
			System.out.println("File not found" + e);
		} catch (IOException ioe) {
			System.out.println("Exception while writing file " + ioe);
		} finally {
			// close the streams using close method
			try {
				if (fos != null) {
					fos.close();
				}
			}

			catch (IOException ioe) {
				System.out.println("Error while closing stream: " + ioe);
			}

		}
		return null;

	}
	
	public static File saveImage(Bitmap b) {
		File dir = new File(Environment.getExternalStorageDirectory()
				.getAbsolutePath() + "/reshary/image/");
		dir.mkdirs();

		File file = new File(Environment.getExternalStorageDirectory()
				.getAbsolutePath()
				+ "/reshary/image/"
				+ System.currentTimeMillis() + ".jpeg");

		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		b.compress(Bitmap.CompressFormat.JPEG, 100, stream);
		byte[] byteArray = stream.toByteArray();

		try {
			file.createNewFile();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		file.mkdirs();
		FileOutputStream fos = null;

		try {
			fos = new FileOutputStream(file);

			// Writes bytes from the specified byte array to this file output
			// stream
			fos.write(byteArray);
			return file;
		}

		catch (FileNotFoundException e) {
			System.out.println("File not found" + e);
		} catch (IOException ioe) {
			System.out.println("Exception while writing file " + ioe);
		} finally {
			// close the streams using close method
			try {
				if (fos != null) {
					fos.close();
				}
			}

			catch (IOException ioe) {
				System.out.println("Error while closing stream: " + ioe);
			}

		}
		return null;
	}

}
